home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / time / vclock / clock.c < prev    next >
C/C++ Source or Header  |  1994-01-12  |  16KB  |  537 lines

  1. /*--------------------------------------------------------------------------*
  2.                 __                 __
  3.                / /                / /__      $RCSfile: clock.c,v $
  4.        ______ / /  ______ ______ / // /      $Revision: 1.9 $
  5.    \/ / ____// /  / __  // ____// _  /       $Date: 1994/01/12 07:46:51 $
  6.      / /___ / /_ / /_/ // /___ / /| |        $Author: tf $
  7.     /_____//___//_____//_____//_/ |_|        $State: Exp $
  8.  
  9.            (c) Copyright 1993 Tobias Ferber, All Rights Reserved.
  10.  
  11.  *--------------------------------------------------------------------------*/
  12.  
  13. #include <exec/types.h>
  14. #include <exec/ports.h>
  15. #include <exec/libraries.h>
  16. #include <libraries/dos.h>
  17. #include <intuition/intuition.h>
  18. #include <time.h>
  19. #include <stdio.h>
  20. #include "timer.h"
  21.  
  22. #define NUMDIGITS  8    /* HH:MM:SS */
  23. #define DHEIGHT   14
  24. #define DWIDTH    16
  25. #define DDIST      5    /* gap between digits */
  26.  
  27. /*#define DEBUG*/
  28. /*#define AMIGA36*/
  29. /*#define CTIME*/
  30.  
  31. static char rcs_id[] = "$VER: $Id: clock.c,v 1.9 1994/01/12 07:46:51 tf Exp $";
  32.  
  33. extern int do_vclock(); /* area.o */
  34. extern SHORT *digits[10], *colon, *nomp;  /* digits.S => chip memory */
  35. static struct IntuitionBase *IntuitionBase= (struct IntuitionBase *)NULL;
  36. static struct Image lcd[8];
  37. BOOL fromWB= FALSE;
  38.  
  39. /* init_screenclock() is where we init our lcd[] array */
  40.  
  41. void init_screenclock(void)
  42. { int i;
  43.   for(i=0;i<NUMDIGITS;i++)
  44.   { lcd[i].LeftEdge  = i*(DWIDTH+DDIST);
  45.     lcd[i].TopEdge   = 0;
  46.     lcd[i].Width     = DWIDTH;
  47.     lcd[i].Height    = DHEIGHT;
  48.     lcd[i].Depth     = 2;
  49.     lcd[i].ImageData = (i==2||i==5) ? colon : digits[0];
  50.     lcd[i].PlanePick = 3;
  51.     lcd[i].PlaneOnOff= 0;
  52.     lcd[i].NextImage = (i==(NUMDIGITS-1)) ? (struct Image *)NULL : &lcd[i+1];
  53.   }
  54. }
  55.  
  56. /* display the current time (hh:mm:ss) in w's RastPort */
  57.  
  58. void set_screenclock(struct Window *w, int h, int m, int s)
  59. {
  60.   static int _h=0,_m=0,_s=0;
  61.  
  62.   if(h!=_h || m!=_m || s!=_s)
  63.   { lcd[0].ImageData= digits[h/10];
  64.     lcd[1].ImageData= digits[h%10];
  65.     lcd[3].ImageData= digits[m/10];
  66.     lcd[4].ImageData= digits[m%10];
  67.     lcd[6].ImageData= digits[s/10];
  68.     lcd[7].ImageData= digits[s%10];
  69.  
  70.     DrawImage(w->RPort, &lcd[0], (w->Width  - NUMDIGITS*(DWIDTH+DDIST))/2,
  71.                                  (w->Height - DHEIGHT)/2 );
  72.     _h=h; _m=m; _s=s;
  73.   }
  74. }
  75.  
  76. #ifdef CTIME
  77. #include <libraries/diskfont.h>
  78. #include <graphics/text.h>
  79.  
  80. ULONG *DiskfontBase= (ULONG *)NULL;
  81.  
  82. void setdiskfont(struct RastPort *rp, char *fname, int fsize)
  83. {
  84.   if(DiskfontBase= (ULONG *)OpenLibrary("diskfont.library",0L))
  85.   { struct TextFont *tf;
  86.     struct TextAttr ta;
  87.     ta.ta_Name= fname;
  88.     ta.ta_YSize= fsize;
  89.     ta.ta_Style= FS_NORMAL;
  90.     ta.ta_Flags= FPF_DISKFONT;
  91.     if(tf= (struct TextFont *)OpenDiskFont(&ta))
  92.       SetFont(rp,tf);
  93.     CloseLibrary(DiskfontBase);
  94.   }
  95. }
  96.  
  97. void render_ctime(struct Window *w, long t)
  98. { char *s= ctime(&t);
  99.   int l= 24; /* strlen(s) */
  100.   SetAPen(w->RPort,3L);
  101.   Move(w->RPort, (w->Width  - TextLength(w->RPort,s,l))/2,
  102.                  3*(w->Height - w->RPort->TxHeight)/4 );
  103.   Text(w->RPort, s,l);
  104. }
  105. #endif
  106.  
  107. #define REDSCALE    0   /* const for do_screenclock() */
  108. #define GREENSCALE  4
  109. #define BLUESCALE   8
  110. #define GREYSCALE  12
  111. #define LCDSCALE   16
  112.  
  113. static short color_table[] = { 0x000,0x500,0x500,0xF00,   /* red table */
  114.                                0x000,0x050,0x050,0x0F0,   /* green table */
  115.                                0x029,0x555,0x555,0xFFF,   /* blue table */
  116.                                0x000,0x555,0x555,0xFFF,   /* grey table */
  117.                                0xCBA,0xBA9,0xBA9,0x543,   /* lcd table */
  118.                                0x029,0x029,0x029,0xFF0,   /* blue+yellow */
  119.                              };
  120.  
  121.  
  122. static struct NewScreen ns= { 0,0, 640,256, 2, 0,0,
  123.                               HIRES,CUSTOMSCREEN|SCREENQUIET,
  124.                               NULL,NULL,NULL,NULL
  125.                             };
  126.             
  127. static struct NewWindow nw= { 0,0, 0,0, -1,-1,
  128.                               MOUSEBUTTONS|RAWKEY|INTUITICKS|MOUSEMOVE,
  129.                               BACKDROP|BORDERLESS|RMBTRAP|REPORTMOUSE|ACTIVATE,
  130.                               NULL,NULL,NULL,NULL,NULL,
  131.                               -1,-1,-1,-1,CUSTOMSCREEN
  132.                             };
  133.  
  134. /*
  135.  * Here we do the screen clock stuff.  ct should be the first index
  136.  * of one of the color_table[] ranges (e.g. REDSCALE)
  137.  * do_screenlock() needs the global IntuitionBase ptr to open the screen
  138.  * and show/update the clock until a MOUSEBUTTONS event comes up.
  139.  */
  140.  
  141. void do_screenclock(int ct)
  142. {
  143.   IntuitionBase= (struct IntuitionBase *)OpenLibrary("intuition.library",0L);
  144.   if(IntuitionBase)
  145.   { struct timerequest *tr= (struct timerequest *)NULL;
  146.  
  147. #ifdef AMIGA36  /* couldn't get this through DICE */
  148. #include <graphics/displayinfo.h>
  149.     if( ((struct Library *)IntuitionBase)->lib_Version >= 36L)
  150.     { struct GfxBase *GfxBase= (struct GfxBase *)OpenLibrary("graphics.library",0L);
  151.       if(GfxBase)
  152.       { struct Screen *lps= (struct Screen *)LockPubScreen("Workbench");
  153.         ULONG modeID= GetVPModeID(&lps->ViewPort);
  154.         if(modeID!=NULL && modeID!=INVALID_ID)
  155.           ns.ViewModes= (UWORD)modeID;   /* problem? */
  156.         else ns.ViewModes= lps->ViewPort.Modes;
  157.  
  158.         ns.Width= lps->Width;
  159.         ns.Height= lps->Height;
  160.  
  161.         UnLockPubScreen(NULL,lps);
  162.         CloseLibrary(GfxBase);
  163.       }
  164.     }
  165.     else
  166. #endif
  167.  
  168.     { struct Screen ws;  /* Workbench Screen data */
  169.       if(GetScreenData(&ws,sizeof(struct Screen),WBENCHSCREEN,NULL))
  170.       { ns.Width= ws.Width;
  171.         ns.Height= ws.Height;
  172.         ns.ViewModes= ws.ViewPort.Modes;
  173.       }
  174.     }
  175.     if((tr= open_timer(NULL,0L)) != (struct timerequest *)NULL)
  176.     { struct MsgPort *tp= tr->tr_node.io_Message.mn_ReplyPort;
  177.       queue_timer(tr,1,0);
  178.       struct Screen *scr= (struct Screen *)NULL;
  179.       if(scr= (struct Screen *)OpenScreen(&ns))
  180.       { struct Window *win= (struct Window *)NULL;
  181.         nw.Screen= scr;
  182.         nw.Width= ns.Width;
  183.         nw.Height= ns.Height;
  184.         LoadRGB4(&scr->ViewPort,&color_table[4*(ct%6)],1L<<(ns.Depth));
  185.         if(win= (struct Window *)OpenWindow(&nw))
  186.         { struct IntuiMessage *imsg;
  187.           BOOL done= FALSE;
  188. #ifdef CTIME
  189.           setdiskfont(win->RPort,"times.font",24);
  190. #endif
  191.           init_screenclock();
  192.           SetPointer(win,nomp,1,1,0,0);
  193.           while(!done)
  194.           { ULONG class;
  195.             long timersigmask = (1L << tp->mp_SigBit),
  196.                  usersigmask  = (1L << win->UserPort->mp_SigBit),
  197.                  breaksigmask = SIGBREAKF_CTRL_C,
  198.  
  199.                  sig= Wait(timersigmask | usersigmask | breaksigmask);
  200.  
  201.             done |= (sig & breaksigmask);
  202.  
  203.             if(sig & timersigmask)
  204.             { while(GetMsg(tp) != (struct Message *)NULL)
  205.                 ;
  206.               if(CheckIO((struct IORequest *)&tr->tr_node))
  207.               { long t;
  208.                 struct tm *lt;
  209.                 time(&t);
  210.                 lt= (struct tm *)localtime(&t);
  211.                 set_screenclock(win,lt->tm_hour,lt->tm_min,lt->tm_sec);
  212. #ifdef CTIME
  213.                 render_ctime(win,t);
  214. #endif
  215.                 queue_timer(tr,1,0);
  216.               }
  217.             }
  218.             if(sig & usersigmask)
  219.             { while(imsg= (struct IntuiMessage *)GetMsg(win->UserPort))
  220.               { class= imsg->Class;
  221.                 ReplyMsg((struct Message *)imsg);
  222.                 done |= (class==MOUSEBUTTONS ||
  223.                          class==RAWKEY       ||
  224.                          class==MOUSEMOVE);
  225.               }
  226.             }
  227.           }
  228.           ClearPointer(win);
  229.           CloseWindow(win);
  230.         }
  231.         CloseScreen(scr);
  232.       }
  233.       purge_timer(tr);
  234.       close_timer(tr);
  235.     }
  236.     CloseLibrary(IntuitionBase);
  237.   }
  238. }
  239.  
  240. static char *howtouse[]= {
  241.  "X",          "/N", "-x", "opening position; left edge (default 0)",
  242.  "Y",          "/N", "-y", "                  top edge (default 0)",
  243.  "WIDTH",      "/N", "-w", "initial window size; width (default 350)",
  244.  "HEIGHT",     "/N", "-h", "                     height (default 55)",
  245.  "SETPEN",     "/N", "-s", "pen used for set segments (default 2)",
  246.  "UNSETPEN",   "/N", "-u", "         for unset segments (default 3)",
  247.  "OUTLINE",    "/N", "-o", "         for segment's outline (default 0)",
  248.  "BACKFILL",   "/N", "-b", "         to fill the background (default 3)",
  249.  
  250.  "BORDERLESS", "/S", "-i", "don't render the window border",
  251.  "BACKDROP",   "/S", "-d", "force vclock to be behind all other windows",
  252.  "NOTITLE",    "/S", "-t", "don't display the date in the window title",
  253.  "NOGADGETS",  "/S", "-g", "do not render system gadgets",
  254.  
  255.  "BLANK",      "/N", "-q", "open screen and show clock w/ given colour table",
  256.  NULL, NULL, NULL, NULL
  257. };
  258.  
  259. main(int argc, char *argv[])
  260. {
  261.   BOOL badopt= FALSE;  /* bad command line option? */
  262.  
  263.   /* defaults */
  264.  
  265.   short x =   0,
  266.         y =   0,
  267.         w = 350,
  268.         h =  55,
  269.         s =   2,
  270.         u =   3,
  271.         o =   0,
  272.         b =   3,
  273.         t =   0,
  274.         q =  -1;
  275.  
  276.   long  f = WINDOWCLOSE|WINDOWDEPTH|WINDOWSIZING|WINDOWDRAG;
  277.  
  278. #ifdef DEBUG
  279.   FILE *fp= fopen("RAM:options","w");
  280.   if(fp)
  281.   { int i=0;
  282.     fprintf(fp,"argc= %d\n",argc);
  283.     for(i=0;i<argc;i++)
  284.       fprintf(fp,"argv[%d]= \"%s\"\n",i,argv[i]);
  285.     fclose(fp);
  286.   }
  287. #endif
  288.  
  289.   if(argc>1)
  290.   { --argc;
  291.     ++argv;
  292.  
  293.     while(argc>0 && !badopt)
  294.     { char *arg= argv[0];
  295.       if(isalpha(*arg))
  296.       { char **aopt= &howtouse[0];
  297.         while(*aopt && stricmp(arg,*aopt))
  298.           aopt= &aopt[4];
  299.         if(*aopt) arg= aopt[2];
  300.       }
  301.       if(*arg=='-')
  302.       { arg++;
  303.         switch(*arg)
  304.         {
  305. /* -x */  case 'x': case 'X':
  306.             if(arg[1]) x= (short)atoi(&arg[1]);
  307.             else
  308.             { argv++;
  309.               argc--;
  310.               if(argc>0) x= (short)atoi(argv[0]);
  311.               else { puts("Error: missing x-position value after keyword");
  312.                      badopt=TRUE;
  313.                    }
  314.             }
  315.             if(x<0)
  316.             { printf("Illegal left edge value %d\n",x);
  317.               badopt= TRUE;
  318.             }
  319.             break;
  320. /* -y */  case 'y': case 'Y':
  321.             if(arg[1]) y= (short)atoi(&arg[1]);
  322.             else
  323.             { argv++;
  324.               argc--;
  325.               if(argc>0) y= (short)atoi(argv[0]);
  326.               else { puts("Error: missing y-position value after keyword");
  327.                      badopt=TRUE;
  328.                    }
  329.             }
  330.             if(y<0)
  331.             { printf("Illegal top edge value %d\n",y);
  332.               badopt= TRUE;
  333.             }
  334.             break;
  335. /* -w */  case 'w': case 'W':
  336.             if(arg[1]) w= (short)atoi(&arg[1]);
  337.             else
  338.             { argv++;
  339.               argc--;
  340.               if(argc>0) w= (short)atoi(argv[0]);
  341.               else { puts("Error: missing width value after keyword");
  342.                      badopt=TRUE;
  343.                    }
  344.             }
  345.             if(w<0)
  346.             { printf("Illegal WIDTH value %d\n",w);
  347.               badopt= TRUE;
  348.             }
  349.             break;
  350. /* -h */  case 'h': case 'H':
  351.             if(arg[1]) h= (short)atoi(&arg[1]);
  352.             else
  353.             { argv++;
  354.               argc--;
  355.               if(argc>0) h= (short)atoi(argv[0]);
  356.               else { puts("Error: missing height value after keyword");
  357.                      badopt=TRUE;
  358.                    }
  359.             }
  360.             if(h<0)
  361.             { printf("Illegal HEIGTH value %d\n",h);
  362.               badopt= TRUE;
  363.             }
  364.             break;
  365. /* -s */  case 's': case 'S':
  366.             if(arg[1]) s= (short)atoi(&arg[1]);
  367.             else
  368.             { argv++;
  369.               argc--;
  370.               if(argc>0) s= (short)atoi(argv[0]);
  371.               else { puts("Error: missing set pen value after keyword");
  372.                      badopt=TRUE;
  373.                    }
  374.             }
  375.             if(s<0 || s>255)
  376.             { printf("Illegal SET pen %d -- should be in [0..255]\n",s);
  377.               badopt= TRUE;
  378.             }
  379.             break;
  380. /* -u */  case 'u': case 'U':
  381.             if(arg[1]) u= (short)atoi(&arg[1]);
  382.             else
  383.             { argv++;
  384.               argc--;
  385.               if(argc>0) u= (short)atoi(argv[0]);
  386.               else { puts("Error: missing unset pen value after keyword");
  387.                      badopt=TRUE;
  388.                    }
  389.             }
  390.             if(u<0 || u>255)
  391.             { printf("Illegal UNSET pen %d -- should be in [0..255]\n",u);
  392.               badopt= TRUE;
  393.             }
  394.             break;
  395. /* -o */  case 'o': case 'O':
  396.             if(arg[1]) o= (short)atoi(&arg[1]);
  397.             else
  398.             { argv++;
  399.               argc--;
  400.               if(argc>0) o= (short)atoi(argv[0]);
  401.               else { puts("Error: missing outline pen value after keyword");
  402.                      badopt=TRUE;
  403.                    }
  404.             }
  405.             if(o<0 || o>255)
  406.             { printf("Illegal OUTLINE pen %d -- should be in [0..255]\n",o);
  407.               badopt= TRUE;
  408.             }
  409.             break;
  410. /* -b */  case 'b': case 'B':
  411.             if(arg[1]) b= (short)atoi(&arg[1]);
  412.             else
  413.             { argv++;
  414.               argc--;
  415.               if(argc>0) b= (short)atoi(argv[0]);
  416.               else { puts("Error: missing backfill value after keyword");
  417.                      badopt=TRUE;
  418.                    }
  419.             }
  420.             if(b<0 || b>255)
  421.             { printf("Illegal BACKFILL pen %d -- should be in [0..255]\n",b);
  422.               badopt= TRUE;
  423.             }
  424.             break;
  425. /* -i */  case 'i': case 'I':
  426.             if(f & WINDOWCLOSE)
  427.               f = BORDERLESS;
  428.             else
  429.               f |= BORDERLESS;
  430.             break;
  431. /* -d */  case 'd': case 'D':
  432.             if(f & WINDOWCLOSE)
  433.               f = BACKDROP;
  434.             else
  435.               f |= BACKDROP;
  436.             break;
  437. /* -t */  case 't': case 'T':
  438.             t= 1;
  439.             break;
  440. /* -g */  case 'g': case 'G':
  441.             f = 0;
  442.             break;
  443. /* -q */  case 'q': case 'Q':
  444.             if(arg[1]) t= (short)atoi(&arg[1]);
  445.             else
  446.             { argv++;
  447.               argc--;
  448.               if(argc>0) q= (short)atoi(argv[0]);
  449.               else q=0;
  450.             }
  451.             break;
  452.           case '?':
  453.             puts(&rcs_id[6]);
  454.             puts("Written by Tobias Ferber for the PUBLIC DOMAIN");
  455.             puts("Refer to vClock.DOC for options.  ? for AmigaDOS help");
  456.             badopt= TRUE;
  457.             break;
  458. /* ?? */  default:
  459.             printf("bad option -%c.\n",*arg);
  460.             badopt= TRUE;
  461.             break;
  462.         }
  463.       }
  464.       else if(*arg=='?')
  465.       { char **usage= &howtouse[0];
  466.         while(*usage)
  467.         { printf("%s%s,",usage[0],usage[1]);
  468.           usage= &usage[4];
  469.         }
  470.         printf("\b:\n\n");
  471.         usage= &howtouse[0];
  472.         while(*usage)
  473.         { printf("%-10s or '%s'  %s\n",usage[0],usage[2],usage[3]);
  474.           usage= &usage[4];
  475.         }
  476.         exit(0);
  477.       }
  478.       else
  479.       { printf("Unknown keyword %s\n",arg);
  480.         badopt= TRUE;
  481.       }
  482.       --argc;
  483.       ++argv;
  484.     }
  485.   }
  486.   if(!badopt)
  487.   { if(q>=0) do_screenclock(q);
  488.     else if( do_vclock(x,y,w,h,s,u,o,b,t,f) )
  489.       puts("vClock failed.");
  490.   }
  491.   if(!fromWB) exit(badopt ? 20:0);
  492. }
  493.  
  494. #include <workbench/workbench.h>
  495. #include <workbench/startup.h>
  496. #include <workbench/icon.h>
  497.  
  498. struct IconBase *IconBase;
  499.  
  500. wbmain(struct WBStartup *WBStartup)
  501. {
  502.   int ac= 0;      /* argument counter */
  503.   char *av[13*2]; /* argument value: 12 keywords, 12 values */
  504.   fromWB= TRUE;
  505.  
  506.   IconBase= (struct IconBase *)OpenLibrary(ICONNAME,LIBRARY_VERSION);
  507.   if(IconBase)
  508.   { struct WBArg *wbarg= WBStartup->sm_ArgList;
  509.     struct DiskObject *icon;
  510.     av[ac++]= (char *)wbarg->wa_Name;
  511.     CurrentDir(wbarg->wa_Lock);
  512.     icon= GetDiskObject(wbarg->wa_Name);
  513.     if(icon)
  514.     { char *ttv, **tt= icon->do_ToolTypes,
  515.                  **usage= &howtouse[0];
  516.  
  517.       while(*usage)
  518.       { ttv= FindToolType(tt,*usage);
  519.         if(ttv)
  520.         { av[ac++]= *usage;
  521.           if(usage[1][1] != 'S')
  522.             av[ac++]= ttv;
  523.         }
  524.         usage= &usage[4];
  525.       }
  526.       (void)main(ac,av);
  527.       FreeDiskObject(icon);
  528.     }
  529.     /* else (we got no icon) -> we were not started from Workbench */
  530.     CloseLibrary(IconBase);
  531.   }
  532.   else
  533.   { av[ac++]= "[icon.library is hiding]";
  534.     (void)main(ac,av);
  535.   }
  536. }
  537.